Ruby 字符串 Frozen 和 unfreeze 的问题

Ruby 字符串 Forzen 和 unfreeze 的问题
字符串处理是学习一门新语言面临的第一个问题 题记

看超人归来的时候,记得里面有个超人叫freeze ? 这家伙有一招,喝口水,然后往外一喷 一切就 freeze 。这不 ruby 也有freeze 。

今天我写的代码中有这样一行:
strTmp = sd[0].to_s.gsub!(/..../ , '' ) ,sd是一个hash

执行的时候出错了:`gsub!': can't modify frozen string (TypeError)
既然forzen了,我想当然的把代码改成:

sdStr = sd[0].to_s
strTmp = sdStr.to_s.gsub!(/..../ , '' )
错误照旧: `gsub!': can't modify frozen string (TypeError)

想起今天孟岩写的:Ruby之symbol研究 ,的确字符串的处理上ruby有很多特色。


3. 为什么可以节省内存?Ruby中的String是可变对象,这一点跟Java、C#、Python都不一样。注意跟某些C++标准库中的COW的 basic_string<T>也不一样。Ruby中每一个String都可以就地改变。可能是因为这个原因,Ruby中两个内容相同的字符 串文本量实际上是两个不同的对象。

a = "hello"
b = "hello"

虽然俩字符串内容都一样,但是你比一下a和b,就知道a.object_id != b.object_id,它们指向的不是同一个对象。结果反而很像未经string pooling优化的C语言的行为。到底immutable好还是mutable好,或者还是貌似聪明的COW好,见仁见智了。不过Ruby的设计在把字 符串用作hash key的时候毛病就大了。比如你写:

h["ruby"].name = "Ruby"
h["ruby"].author = "matz"
h["ruby"].birth_year = 1995

的时候,"ruby"这个字符串动态生成了三次,占用三倍内存。这就严重地浪费了内存。而用:ruby做为key,因为在整个运行过程中,Ruby runtime保证名为:ruby的symbol对象只有一个,所以就不用生成三个,节省内存。



在看参考手册的时候才发现 ruby 的 string 有 freeze 方法 ,却没有提供 unfreeze 。最后只好老老实实看参考手册用:


sdUrl = sd[0].to_s.dup 的方法解决了 frozen 的问题。

不过 matz 说或许未来会提供吧

Uh, maybe. Some part of string copy-on-write system depends on the
fact that frozen strings would never be modified. I'm not sure proper
copying on those two functions make unfreeze possible. When I confirm
it, I would happily add Object#unfreeze to the future Ruby.
matz.


Ruby中不只是字符串会碰到freeze的问题,Array 和 Hash 的 frozen 使用更需要注意了,可以参考下面的文章:

Ruby Array and Hash frozen behavior

接触ruby一段时间了,ruby给了我很快乐的感觉,ruby比python更自然。


以前分析 java nanning (南宁) aop 模块的一些经验 再加上现在用ruby的感觉,发现 ruby 作为领域语言确实有很多优势,这不
A taste of evil.rb: using DL to unfreeze objects 又给了我更多的启发。

相关链接

Ruby 字符串 Forzen 和 unfreeze 的问题
Ruby 字符串 Forzen 和 unfreeze 的问题
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由于代码过长,我无法在此提供完整的前端代码和合约代码。但我可以提供一些示例代码来说明如何实现这个系统。 以下是一个简单的合约示例,用于管理用户信息: ``` pragma solidity >=0.4.22 <0.7.0; contract UserManagement { struct User { bytes publicKey; bytes encryptedPrivateKey; bool frozen; } mapping(address => User) private users; mapping(address => bool) private admins; function register(bytes memory _publicKey, bytes memory _encryptedPrivateKey) public { // Check if user already exists require(users[msg.sender].publicKey.length == 0, "User already exists"); // Add user to mapping users[msg.sender] = User(_publicKey, _encryptedPrivateKey, false); } function login(bytes memory _publicKey, bytes memory _encryptedPrivateKey) public view returns (bool) { // Check if user exists require(users[msg.sender].publicKey.length != 0, "User does not exist"); // Check if public key and encrypted private key match return keccak256(users[msg.sender].publicKey) == keccak256(_publicKey) && keccak256(users[msg.sender].encryptedPrivateKey) == keccak256(_encryptedPrivateKey); } function freezeUser(address _userAddress) public { // Check if caller is admin require(admins[msg.sender], "Only admins can freeze users"); // Freeze user users[_userAddress].frozen = true; } function unfreezeUser(address _userAddress) public { // Check if caller is admin require(admins[msg.sender], "Only admins can unfreeze users"); // Unfreeze user users[_userAddress].frozen = false; } function isAdmin() public view returns (bool) { // Check if caller is admin return admins[msg.sender]; } function addAdmin(address _adminAddress) public { // Check if caller is admin require(admins[msg.sender], "Only admins can add other admins"); // Add admin admins[_adminAddress] = true; } function removeAdmin(address _adminAddress) public { // Check if caller is admin require(admins[msg.sender], "Only admins can remove other admins"); // Remove admin admins[_adminAddress] = false; } } ``` 以下是一个简单的数据存储合约示例,用于存储用户信息和其他相关数据: ``` pragma solidity >=0.4.22 <0.7.0; contract DataStorage { struct UserData { string name; string email; uint age; } mapping(address => UserData) private userData; function setUserData(string memory _name, string memory _email, uint _age) public { userData[msg.sender] = UserData(_name, _email, _age); } function getUserData(address _userAddress) public view returns (string memory, string memory, uint) { return (userData[_userAddress].name, userData[_userAddress].email, userData[_userAddress].age); } // Other functions for storing and retrieving data... } ``` 以下是一个简单的前端页面示例,用于调用智能合约的功能: ``` // Import web3.js library import Web3 from 'web3'; // Set up web3 provider const provider = new Web3.providers.HttpProvider('http://localhost:8545'); const web3 = new Web3(provider); // Set up contract object const userManagementContractAddress = '0x123...'; const userManagementContractABI = [...]; const userManagementContract = new web3.eth.Contract(userManagementContractABI, userManagementContractAddress); // Register user userManagementContract.methods.register(publicKey, encryptedPrivateKey).send({from: userAddress}) .on('receipt', function(receipt) { // Handle receipt... }) .on('error', function(error) { // Handle error... }); // Login user userManagementContract.methods.login(publicKey, encryptedPrivateKey).call({from: userAddress}) .then(function(result) { // Handle result... }) .catch(function(error) { // Handle error... }); // Freeze user userManagementContract.methods.freezeUser(userAddress).send({from: adminAddress}) .on('receipt', function(receipt) { // Handle receipt... }) .on('error', function(error) { // Handle error... }); // Set user data const dataStorageContractAddress = '0x456...'; const dataStorageContractABI = [...]; const dataStorageContract = new web3.eth.Contract(dataStorageContractABI, dataStorageContractAddress); dataStorageContract.methods.setUserData(name, email, age).send({from: userAddress}) .on('receipt', function(receipt) { // Handle receipt... }) .on('error', function(error) { // Handle error... }); // Get user data dataStorageContract.methods.getUserData(userAddress).call({from: callerAddress}) .then(function(result) { // Handle result... }) .catch(function(error) { // Handle error... }); ``` 请注意,这些示例代码仅用于说明如何实现基于fisco bcos的智能合约公钥注册登录系统。实际实现中需要更详细的代码和逻辑来确保安全和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值